package com.xyt.imei.core.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.luminary.common.framework.dao.GenericDao;
import com.luminary.common.framework.service.impl.GenericServiceImpl;
import com.xyt.imei.core.dao.ExtraStoreDao;
import com.xyt.imei.core.dao.StoreDao;
import com.xyt.imei.core.meta.ValidateConstants;
import com.xyt.imei.core.model.converter.ExtraStoreConverter;
import com.xyt.imei.core.model.dto.ExtraStoreExcelDTO;
import com.xyt.imei.core.model.po.ExtraStore;
import com.xyt.imei.core.model.po.Store;
import com.xyt.imei.core.model.po.User;
import com.xyt.imei.core.model.vo.ErrorInfoVO;
import com.xyt.imei.core.model.vo.ExtraStoreVO;
import com.xyt.imei.core.service.ExtraStoreService;

import lombok.Data;

@Service
public class ExtraStoreServiceImpl extends GenericServiceImpl<ExtraStore, String> implements ExtraStoreService {

	@Autowired
	private ExtraStoreConverter extraStoreConverter;
	
	@Autowired
	private ExtraStoreDao extraStoreDao;
	
	@Autowired
	private StoreDao storeDao;
	
	@Override
	protected GenericDao<ExtraStore, String> getGenericDao() {
		return this.extraStoreDao;
	}

	@Override
	@Transactional
	public ValidateInfo addExtraStore(List<ExtraStoreExcelDTO> dto, User user) throws Exception {
		
		ValidateInfo validateInfo = validate(dto, user);
		if(validateInfo.getExtraStore() != null && !validateInfo.getExtraStore().isEmpty()) {
			extraStoreDao.insertByBatch(validateInfo.getExtraStore());
		}
		return validateInfo;
		
	}
	
	private ValidateInfo validate(List<ExtraStoreExcelDTO> dto, User user) {
		
		ValidateInfo validateInfo = new ValidateInfo();
		
		List<ErrorInfoVO> errorInfoList = new ArrayList<ErrorInfoVO>();
		List<ExtraStore> extraStoreList = new ArrayList<ExtraStore>();
		dto.forEach(d -> {
			
			int count = 0;
			for(ExtraStoreExcelDTO dd : dto) {
				if(d.getImeiNo().equals(dd.getImeiNo())) {
					count++;
				}
			};
			
			String imeiNo = d.getImeiNo();
			Date activeDate = d.getActiveDate();
			
			if(count > 1) {
				ErrorInfoVO vo = new ErrorInfoVO();
				vo.setImeiNo(imeiNo);
				vo.setRemark("串号重复");
				errorInfoList.add(vo);
			}
			else if(imeiNo == null) {
				ErrorInfoVO vo = new ErrorInfoVO();
				vo.setImeiNo(imeiNo);
				vo.setRemark("串号为空");
				errorInfoList.add(vo);
			}
			else if(!imeiNo.matches(ValidateConstants.REGEXP_IMEI)) {
				ErrorInfoVO vo = new ErrorInfoVO();
				vo.setImeiNo(imeiNo);
				vo.setRemark("串号格式不正确");
				errorInfoList.add(vo);
			} 
			else if(activeDate == null) {
				ErrorInfoVO vo = new ErrorInfoVO();
				vo.setImeiNo(imeiNo);
				vo.setRemark("激活时间为空");
				errorInfoList.add(vo);
			}
			else {
				Store store = storeDao.selectByPrimaryKey(imeiNo);
				ExtraStore extraStore = extraStoreDao.selectByPrimaryKey(imeiNo);
				if(store != null) {
					ErrorInfoVO vo = new ErrorInfoVO();
					vo.setImeiNo(imeiNo);
					vo.setRemark("正常库存中已经存在该串号");
					errorInfoList.add(vo);
				} 
				else if(extraStore != null) {
					ErrorInfoVO vo = new ErrorInfoVO();
					vo.setImeiNo(imeiNo);
					vo.setRemark("额外库存中已经存在该串号");
					errorInfoList.add(vo);
				}
				else {
					extraStore = new ExtraStore();
					extraStore.setImeiNo(imeiNo);
					extraStore.setActiveDate(d.getActiveDate());
					extraStore.setCreateBy(user.getUserId());
					extraStore.setCreateDate(new Date());
					extraStoreList.add(extraStore);
				}
			}
			
			validateInfo.setErrorInfo(errorInfoList);
			validateInfo.setExtraStore(extraStoreList);
			
		});
		
		return validateInfo;
		
	}
	
	@Data
	public static class ValidateInfo {
		
		List<ErrorInfoVO> errorInfo;
		
		List<ExtraStore> extraStore;
		
	}

	@Override
	public Workbook export() throws Exception {
		
		Map<String, Object> params = new HashMap<String, Object>();
		long count = extraStoreDao.selectRecordCountByPage(params);
		
		Workbook workbook = null;
		
		if(count > 10000) {
			long rest = 0;
			long parts = count % 10000 == 0 ? count / 10000 : count / 10000 +1;
			
			for(int i = 0; i < parts - 1; i++) {
				params.put("startRow", 10000 * i);
				params.put("pageSize", 10000);
				
				List<ExtraStore> extraStore = extraStoreDao.selectPageDataByPage(params);
				List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
				try {
					workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
				} catch (Exception e) {
					e.printStackTrace();
					return null;
				} 
				rest = count - 10000;
			}
			
			params.put("startRow", 10000 * (parts - 1));
			params.put("pageSize", rest);
			
			List<ExtraStore> extraStore = extraStoreDao.selectPageDataByPage(params);
			List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
			
			try {
				workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			} 
		} else if(count > 0) {
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			params.put("startRow", 0);
			params.put("pageSize", count);

			List<ExtraStore> extraStore = extraStoreDao.selectPageDataByPage(params);
			List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
			
			try {
				workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			} 
		}

		return workbook;
		
	}
	
	@Override
	public Workbook exportDiff() throws Exception {
		
		Map<String, Object> params = new HashMap<String, Object>();
		long count = extraStoreDao.selectRecordCountDiffByPage(params);
		
		Workbook workbook = null;
		
		if(count > 10000) {
			long rest = 0;
			long parts = count % 10000 == 0 ? count / 10000 : count / 10000 +1;
			
			for(int i = 0; i < parts - 1; i++) {
				params.put("startRow", 10000 * i);
				params.put("pageSize", 10000);
				
				List<ExtraStore> extraStore = extraStoreDao.selectPageDataDiffByPage(params);
				List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
				try {
					workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
				} catch (Exception e) {
					e.printStackTrace();
					return null;
				} 
				rest = count - 10000;
			}
			
			params.put("startRow", 10000 * (parts - 1));
			params.put("pageSize", rest);
			
			List<ExtraStore> extraStore = extraStoreDao.selectPageDataByPage(params);
			List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
			
			try {
				workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			} 
		} else if(count > 0) {
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			params.put("startRow", 0);
			params.put("pageSize", count);

			List<ExtraStore> extraStore = extraStoreDao.selectPageDataByPage(params);
			List<ExtraStoreVO> extraStoreVO = extraStoreConverter.po2vo(extraStore);
			
			try {
				workbook = ExcelExportUtil.exportBigExcel(new ExportParams(null, "Sheet1"), ExtraStoreVO.class, extraStoreVO);
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			} 
		}

		return workbook;
		
	}

}
